/*******************************************************************************
** 文件名称：serialport.h
** 文件作用：串口处理--中间层
** 编写作者：TomFree <付瑞彪>
** 编写时间：2019-12-21
** 文件备注：
**
** 更新记录：
**           2019-12-21 -> 创建文件                                 <Tom Free>
**
**           1 Tab == 4 Spaces     UTF-8     ANSI C Language
*******************************************************************************/
#ifndef __SERIALPORT_H__
#define __SERIALPORT_H__

#include "typedef.h"
#include "queue.h"

/* 串口数量定义 */
#define SERIAL_PORT_NUM_MAX     1U

#ifndef SERIAL_PORT_NUM_MAX
/* 警告输出 */
#warning Tips -- The total number of serial ports is not defined. System will restore default 1.
/* 默认串口数量为1 */
#define SERIAL_PORT_NUM_MAX     1U
#endif  /* SERIAL_PORT_NUM_MAX */

#if (SERIAL_PORT_NUM_MAX == 0)
/* 警告输出 */
#warning Tips -- The total number of serial ports is 0. System will restore default 1.
/* 取消之前的定义 */
#undef  SERIAL_PORT_NUM_MAX
/* 默认串口数量为1 */
#define SERIAL_PORT_NUM_MAX     1U
#endif  /* SERIAL_PORT_NUM_MAX == 0 */

/* 串口驱动 */
typedef struct _SERIAL_PORT_DRIVE
{
    GM_BOOL (*QueryRxComplete)();       /* 查询接收完成 */
    GM_BOOL (*QueryTxIdle)();           /* 查询发送空闲 */
    GM_U8   (*RxByte)();                /* 接收一个字节 */
    void    (*TxByte)(GM_U8 tx_data);   /* 发送一个字节 */
} SERIAL_PORT_DRIVE;

/*******************************************************************************
** 函数名称：SerialPort_DriveInit
** 函数作用：驱动初始化
** 输入参数：sp_num - 串口号，从0开始，最大不可超过[SERIAL_PORT_NUM_MAX]
**          drv    - 驱动指针
** 输出参数：是否成功
** 使用范例：SerialPort_DriveInit(0, drv);
** 函数备注：
*******************************************************************************/
GM_BOOL SerialPort_DriveInit(GM_U8 sp_num, SERIAL_PORT_DRIVE* drv);

/*******************************************************************************
** 函数名称：SerialPort_QueueInit
** 函数作用：初始化串口的队列
** 输入参数：sp_num      - 串口号，从0开始，最大不可超过[SERIAL_PORT_NUM_MAX]
**          rx_buf      - 接收队列缓冲区起始地址
**          rx_buf_size - 接收队列缓冲区大小
**          tx_buf      - 发送队列缓冲区起始地址
**          tx_buf_size - 发送队列缓冲区大小
** 输出参数：是否成功
** 使用范例：SerialPort_QueueInit(0, &buf1, 10, &buf2, 30);
** 函数备注：
*******************************************************************************/
GM_BOOL SerialPort_QueueInit(GM_U8 sp_num,          /* 串口号 */
                             GM_U8* rx_buf,         /* 接收buf地址 */
                             GM_U16 rx_buf_size,    /* 接收buf长度 */
                             GM_U8* tx_buf,         /* 发送buf地址 */
                             GM_U16 tx_buf_size);

/*******************************************************************************
** 函数名称：SerialPort_ReceiveByteHandler
** 函数作用：串口接收一个字符处理
** 输入参数：sp_num  - 串口号，从0开始，最大不可超过[SERIAL_PORT_NUM_MAX]
** 输出参数：是否保存成功
** 使用范例：GM_BOOL res = SerialPort_ReceiveByteHandler(0);
** 函数备注：此函数一般放在接收中断中或查询接收标志处理任务中
*******************************************************************************/
GM_BOOL SerialPort_ReceiveByteHandler(GM_U8 sp_num);

/*******************************************************************************
** 函数名称：SerialPort_SendByteHandler
** 函数作用：串口发送一个字符处理
** 输入参数：sp_num - 串口号，从0开始，最大不可超过[SERIAL_PORT_NUM_MAX]
** 输出参数：是否发送OK，GM_TRUE - 发送OK，GM_FALSE - 数据发完，空闲了
** 使用范例：SerialPort_SendByteHandler
** 函数备注：此函数一般放在发送中断中或查询发送标志处理任务中
*******************************************************************************/
GM_BOOL SerialPort_SendByteHandler(GM_U8 sp_num);

/*******************************************************************************
** 函数名称：SerialPort_WriteByte
** 函数作用：无阻塞写数据
** 输入参数：sp_num  - 串口号，从0开始，最大不可超过[SERIAL_PORT_NUM_MAX]
**          tx_data - 待发送数据
** 输出参数：无
** 使用范例：SerialPort_WriteByte();
** 函数备注：
*******************************************************************************/
void SerialPort_WriteByte(GM_U8 sp_num, GM_U8 tx_data);

/*******************************************************************************
** 函数名称：SerialPort_ReadByte
** 函数作用：无阻塞读数据
** 输入参数：sp_num  - 串口号，从0开始，最大不可超过[SERIAL_PORT_NUM_MAX]
**          rx_data - 读取的数据
** 输出参数：是否接收到数据
** 使用范例：SerialPort_ReadByte();
** 函数备注：
*******************************************************************************/
GM_BOOL SerialPort_ReadByte(GM_U8 sp_num, GM_U8* rx_data);

/*******************************************************************************
** 函数名称：SerialPort_PutString
** 函数作用：打印字符串
** 输入参数：sp_num  - 串口号，从0开始，最大不可超过[SERIAL_PORT_NUM_MAX]
**          str     - 字符串
** 输出参数：无
** 使用范例：SerialPort_PutString(0, "hello\r\n");
** 函数备注：
*******************************************************************************/
void SerialPort_PutString(GM_U8 sp_num, const char * str);

/*******************************************************************************
** 函数名称：SerialPort_Printf
** 函数作用：printf函数
** 输入参数：sp_num  - 串口号，从0开始，最大不可超过[SERIAL_PORT_NUM_MAX]
**          fmt - 格式化字符串
** 输出参数：无
** 使用范例：SerialPort_Printf(0, "%d\r\n", 287);
** 函数备注：
*******************************************************************************/
void SerialPort_Printf(GM_U8 sp_num, const char * fmt, ...);

#endif  /* __SERIALPORT_H__ */
